package com.lbd.finance.service.impl;

import com.lbd.bonus.bean.Bonus;
import com.lbd.commons.Constants;
import com.lbd.finance.bean.vo.ExportInvestFlowDetailVo;
import com.lbd.finance.bean.vo.InvestFlowDetailVo;
import com.lbd.finance.service.InvestFlowDetailService;
import com.lbd.system.bean.Record;
import com.lbd.system.service.DictionaryService;
import com.lbd.system.service.RecordService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateFormatUtils;
import org.apache.log4j.Logger;
import org.hibernate.SQLQuery;
import org.hibernate.transform.Transformers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.EntityManager;
import javax.persistence.Query;
import java.math.BigDecimal;
import java.util.*;


@Service
@Transactional
public class InvestFlowDetailServiceImpl implements InvestFlowDetailService {
    private final Logger log = Logger.getLogger(this.getClass());

    @Autowired
    public EntityManager em;
    @Autowired
    private RecordService recordService;
    @Autowired
    private DictionaryService dictionaryService;

    /**
     * 获取投资流水列表信息
     *
     * @param page               页码
     * @param rows               行数
     * @param investFlowDetailVo 投资查询条件
     * @return
     */
    @Override
    public Page getInvestFlowDetailList(int page, int rows, InvestFlowDetailVo investFlowDetailVo) {

        Map<String, Object> parameter = new HashMap<>();
        String sql = buildNativeSql(investFlowDetailVo, parameter);
        return recordService.findByPageNativeQuery(page, rows, parameter, sql);
    }

    /**
     * 获取导出投资信息
     *
     * @param investFlowDetailVo 查询参数
     * @return
     */
    @Override
    public List<ExportInvestFlowDetailVo> getExportInvesetFlowList(InvestFlowDetailVo investFlowDetailVo) {
        Map<String, Object> parameter = new HashMap<>();
        String sql = buildNativeSql(investFlowDetailVo, parameter);
        Query nativeQuery = em.createNativeQuery(sql);
        nativeQuery.unwrap(SQLQuery.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
        for (String key : parameter.keySet()) {
            nativeQuery.setParameter(key, parameter.get(key));
        }
        List<Map> resultList = nativeQuery.getResultList();
        List<ExportInvestFlowDetailVo> exportList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(resultList)) {
            String keys = Constants.DIC_BONUS_TYPE.concat(",").concat(Constants.DIC_CHANNEL_TYPE);
            Map<String, Map<String, String>> dicMap = dictionaryService.getDictionary(keys);
            ExportInvestFlowDetailVo investVo;
            String expecInterest = "";//预期年化收益率
            String bonusType = "";//优惠券类型
            String bonusValue = "";//优惠券面值或利率
            for (Map map : resultList) {
                investVo = new ExportInvestFlowDetailVo();
                if (null != map.get("name"))
                    investVo.setName((String) map.get("name"));
                if (null != map.get("telephone"))
                    investVo.setTelephone((String) map.get("telephone"));
                if (null != map.get("amount"))
                    investVo.setAmount((BigDecimal) map.get("amount"));
                if (null != map.get("expecInterest")) {
                    expecInterest = String.valueOf((Double) map.get("expecInterest"));
                    expecInterest = expecInterest.replaceAll("0+?$", "").replaceAll("[.]$", "").concat("%");
                    investVo.setExpecInterest(expecInterest);
                }
                if (null != map.get("bonusType")) {
                    bonusType = (String) map.get("bonusType");
                    investVo.setBonusType(dicMap.get(Constants.DIC_BONUS_TYPE).get(bonusType));
                }
                if (null != map.get("bonusValue")) {
                    bonusValue = (String) map.get("bonusValue");

                    //判断为加息券，在预期年化收益上增加显示
                    if (StringUtils.equals(bonusType, Bonus.BONUS_TYPE_2)) {
                        bonusValue = BigDecimal.valueOf(Double.valueOf(bonusValue)).multiply(BigDecimal.valueOf(100)).toString();
                        bonusValue = bonusValue.replaceAll("0+?$", "").replaceAll("[.]$", "").concat("%");
                        investVo.setBonusValue(bonusValue);
                        expecInterest = expecInterest.concat("+").concat(bonusValue);
                        investVo.setExpecInterest(expecInterest);
                    } else {
                        investVo.setBonusValue(bonusValue);
                    }
                }
                if (null != map.get("contractNo"))
                    investVo.setContractNo((String) map.get("contractNo"));
                if (null != map.get("trdNo"))
                    investVo.setTrdNo((String) map.get("trdNo"));
                if (null != map.get("finishTime"))
                    investVo.setTrdTime(DateFormatUtils.format((Date) map.get("finishTime"), "yyyy-MM-dd HH:mm:ss"));
                if (null != map.get("platform"))
                    investVo.setTrdType(dicMap.get(Constants.DIC_CHANNEL_TYPE).get((String) map.get("platform")));
                if (null != map.get("actualAmount"))
                    investVo.setFactAmount((BigDecimal) map.get("actualAmount"));

                exportList.add(investVo);
            }

        } else {
            return new ArrayList<>();
        }

        return exportList;
    }

    /**
     * 构建查询语句
     *
     * @param investFlowDetailVo
     * @param parameter
     * @return
     */
    private String buildNativeSql(InvestFlowDetailVo investFlowDetailVo, Map<String, Object> parameter) {
        StringBuilder jbpSql = new StringBuilder("SELECT ")
                .append(" r.trade_no trdNo,")
                .append("t.`loan_number` contractNo,")
                .append(" u.`telephone` telephone,")
                .append("u.`name` name,")
                .append("r.platform platform,")
                .append(" r.amount amount,")
                .append("r.actual_amount actualAmount,")
                .append("b.`type` bonusType,")
                .append(" b.`value` bonusValue,")
                .append("round(t.nhsyl*100,2) expecInterest,")//预期年化收益界面展现*100
                .append("r.finish_time finishTime")
                .append(" FROM trading_record r  LEFT JOIN `user` u   ON r.user_id = u.id ")
                .append("  LEFT JOIN `order` o  ON r.order_id = o.`id` ")
                .append(" LEFT JOIN target_info t  ON o.`target_id` = t.`id` ")
                .append(" LEFT JOIN sys_user_bonus s   ON s.`order_id` = o.id ")
                .append("  LEFT JOIN bonus b  ON b.id = s.`bonus_id` ")
                .append("WHERE r.state =").append(Record.STATE_SUCCESS)//状态为成功
                .append("");

        if (StringUtils.isNotBlank(investFlowDetailVo.getTargetNo())) {
            jbpSql.append(" and t.loan_number like:targetNo");
            parameter.put("targetNo", "%".concat(investFlowDetailVo.getTargetNo()).concat("%"));
        }
        if (StringUtils.isNotBlank(investFlowDetailVo.getTelephone())) {
            jbpSql.append(" and u.telephone like:telephone");
            parameter.put("telephone", "%".concat(investFlowDetailVo.getTelephone()).concat("%"));
        }
        if (StringUtils.isNotBlank(investFlowDetailVo.getTrdNo())) {
            jbpSql.append(" and r.trade_no like:tradeNo");
            parameter.put("tradeNo", "%".concat(investFlowDetailVo.getTrdNo()).concat("%"));
        }
        if (StringUtils.isNotBlank(investFlowDetailVo.getTrdType())) {
            jbpSql.append(" and r.platform =:tradeType");
            parameter.put("tradeType", investFlowDetailVo.getTrdType());
        }
        if (null != investFlowDetailVo.getBeginTime()) {
            jbpSql.append(" and r.finish_time >=:startTime");
            parameter.put("startTime", investFlowDetailVo.getBeginTime());
        }
        if (null != investFlowDetailVo.getEndTime()) {
            jbpSql.append(" and r.finish_time <=:endTime");
            parameter.put("endTime", investFlowDetailVo.getEndTime());
        }
        jbpSql.append(" and  r.type =").append(Record.CATEGORY_3);//类型为投资
        jbpSql.append(" order by r.finish_time desc");
        return jbpSql.toString();
    }
}
